<html>

<body id=body style='font-family:arial'>
<div style='width:800px;background:#eeffaa;border-radius:10px;padding:10px;border:1px solid green;margin:auto;box-shadow: 4px 4px 2px rgba(0,0,0,0.5);'>
<style>
#xdecode { 
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
    }
</style>
<table width=100%><tr valign=top><td>
<div>GCODE PREVIEW</div><hr>
View angle<input id=angle value="65,35" size=5><button onclick="init2d(0);rendergcode();">View</button>
<div>Preview:</div>
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #d3d3d3;"></canvas>
<table width=200><tr><td><button onclick="init2d(-45);rendergcode();"> &lt</button><button onclick="randomcolor();rendergcode()">Color</button>
<td align=right><button onclick="init2d(45);rendergcode();">&gt</button>
</table>
<td>
<div>UPLOAD TO MACHINE</div><hr>
<div id=info>Info:</div>
Job name <input id=jobname size=10 value=gcode><br>
<button id=btclick onclick="upload()">Upload</button> <progress id=progress1 min="0" max="100" value="0" style="width:100px">0% complete</progress><br>

<hr>
<div>ON MACHINE GCODE</div>
<br><button id=btclick onclick="startprint()">Start print</button>&nbsp;
<button id=btclick onclick="stopprint()">Stop print</button><br>
<br>
<button id=btclick onclick="pauserint()">Pause print</button>&nbsp;
<button id=btclick onclick="resumerint()">Resume print</button><br>
<br>
<button id=btclick onclick="homing()">Home</button>&nbsp;
<button id=btclick onclick="heating()">Heating</button><br>
<button id=btclick onclick="cooling()">Cooling</button><br>
<hr>
<a href="jobs" target=job><button>View machine jobs</button></a> 
<td>
<div>WEBSOCKET GCODE SENDER</div>
<hr>
Machine IP <input id=wsip size=10 class=saveit value="">
<div id=status>Status:not connected </div><button id=wsconnect onclick="connectwebsock()">Connect</button>

<br>
EEPROM<br>
<button  id=bt3eeprom>Read</button><select id=eepromid>
	
</select><input id=eepromval size=3><button  id=bt3seteeprom>Set EEPROM</button>
<hr>
GCODE 
<button id=btdecode onclick="decode()">Decode</button><br>
<div id=decode style="font-size:8pt;width:300px;height:200px">
</div><hr>
<button id=btexecute onclick="executedecode()">Print</button>
<button id=btpause onclick="pause()">PAUSE</button>&nbsp;<button onclick="hardstop()">HALT</button>&nbsp;&nbsp;<Button onclick="sendg()">Send GCODE</button>
<div id=info3d></div>
</table>
<hr>
<table width=100%><tr><td>
Paste or drag a gcode file here to begin print.
<td align='right'><button onclick="printhub()" id=btload>Load GCODE</button> from <a target=hub href="http://www.karyahub3d.xyz">KARYAHUB3D.XYZ</a>
</table>
</div>
<script>
var wsconnected=0;
</script>
<script src="websocket.js"></script>

<script src="ace.js" type="text/javascript" charset="utf-8"></script>
<script>
    var editor = ace.edit("decode");
//	editor.setReadOnly(true);
//    editor.session.setMode("ace/mode/gcode");



var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function mround(x) {
    return parseFloat(x).toFixed(2);
}
function mround4(x) {
    return parseFloat(x).toFixed(4);
}

function $(id) {
    return document.getElementById(id);
}
function getvalue(el) {
    return $(el).value;
}

function setvalue(el, val) {
    $(el).value = val;
}
function log(text) {
    $('log').value += text + '\n';
}


function setevent(ev, bt, act) {
    $(bt).addEventListener(ev, act, false);
}

function setclick(bt, act) {
    setevent("click", bt, act);
}

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(find, 'g'), replace);
}
var packages=[];
var compress=[];
function write(w,s){
	if (s>0)compress.push(w & 255);
	if (s>1)compress.push((w >> 8) & 255);
	if (s>2)compress.push((w >> 16) & 255);	
}
var holdpos=0;
function hold(){
	holdpos=compress.length-1;
}

var sendg1="";
function sendg(){
	var s=prompt("GCODE Command",sendg1);
	if (s) {
		sendg1=s;
		sendgcode(s);
	}
}
function executedecode(){
    var bt = document.getElementById('btexecute');
    if (bt.innerHTML == "Print") {
        execute(editor.getValue());
        bt.innerHTML = "Stop";
    } else {
        stopit();
        sendgcode("M2");
    }
}
function pause() {
    var bt = document.getElementById('btpause');
    if (bt.innerHTML == "PAUSE") {
        running = 0;
        sendgcode("M3 S200 P10");
        bt.innerHTML = "RESUME";
    } else {
        running = 1;
        sendgcode("M3 S200");
        nextgcode();
        bt.innerHTML = "PAUSE";
    }
}
function hardstop() {
    sendgcode("M2");
    sendgcode("G0 Z2 F5000");
    sendgcode("G0 X0 Y0");
    px=0;
	py=0;
	pz=2;
    stopit();
}


var cntg28=0;
var totalgcode=0;
function endcompress(){}
var lx=-10.0;
var ly=-10.0;
var lz=-10.0;
var le=-10.0;
var lf=-10.0;
var lh=0;
var ole=0;
var oxmin=0;
var oxmax=0;
var oymin=0;
var oymax=0;
var ozmin=0;
var ozmax=0;
var eE=0;
var E=0;
var F0=0;
var F1=0;
var isRel=0;
var overtex=[]; // will hold x,y,z
var lines=[]; // will hold n1,n2 that index point to vertex

var zdeg=45;
var xdeg=35;
var sinz=0.707;
var cosz=0.707;
var sinx=0.707;
var cosx=0.707;
var filament=0;
var printtime=0;
function init2d(v){
  //return;	
  if (!v){
	  v=(getvalue("angle")).split(",");
	  zdeg=v[0]*1;
	  xdeg=v[1]*1;
  } else zdeg+=v;	
  sinz=Math.sin(zdeg*0.0174533);
  cosz=Math.cos(zdeg*0.0174533);
  sinx=Math.sin(xdeg*0.0174533);
  cosx=Math.cos(xdeg*0.0174533);
}
init2d(0);
var eSize=2;
var eMul=500;
var xyMul=100;
var eBound=10000;
var xyscale=100;

if (eSize==1){
	eMul=50;
	eBound=127;
}
function transform(v3d){
	var x2=v3d[0]*cosz-v3d[1]*sinz;
	var y1=v3d[0]*sinz+v3d[1]*cosz;
	
	var y2=y1*cosx-v3d[2]*sinx;
	var z2=y1*sinx+v3d[2]*cosx;
	
	return [x2,y2,-z2];
	
}
var ln=0;
var warnoverflow=0;
function addgcode(g){
    // read gcode
	ln++;
    totalgcode += g.length;
    gd = {};
    lv = "";
    lk = "";
    gk = "";
    g = g.toUpperCase();
    for (var i = 0; i < g.length; i++) {
        c = g[i];

        if (".0123456789-".indexOf(c) >= 0) {
            lv += c;
        }
        if ((" ;MGXYZEFST".indexOf(c) >= 0) || (i == g.length - 1)) {
            if (lv) {
                gk += lk;
                gd[lk] = lv * 1;
                lv = "";
            }
            if ("MGXYZEFST".indexOf(c) >= 0) lk = c;
        }
        if (c == ';') break;
    }

    var h = 0;
    var f = 0;
    var s = 0;
    var x = 0;
    // generic Gcode motion process before compress

    if (gk.indexOf('G') + 1) {
        switch (gd['G']) {
            case 90: // absolute
                isRel = 0;
                break;
            case 91:
                isRel = 1;
                break;
        }
    }

    //


    if (gk.indexOf('M') + 1) {
        h = 1;
        switch (gd['M']) {
            case 3: // spindle on
                h |= 0;
                break;
            case 109:
                h |= 1 << 1;
                break;
            case 2:
                h |= 2 << 1;
                break; // final
            default:
                return; // not implemented
        }
        s = gd['S'];
		if (s==undefined)s=255;
        h |= 1 << 3;
        write(h, 1);
        write(s, 1);
        console.log(ln+" M"+gd['M']+" S"+s);
    }
    if (gk.indexOf('G') + 1) {
        h = 0;
        var G = gd['G'];
        switch (G) {
            case 0:
                h |= 0;
                break; // we need bit 1 as identify a repeat header
            case 1:
                h |= 1 << 1;
                break;
            case 28:
                h |= 2 << 1;
                cntg28--;
                break;
            case 92:
                h |= 3 << 1;
                ole = 0;
                E = 0;
                eE = 0;
                console.log("W" + E);
                break;
            default:
                return; // not implemented
        }
        var isF = gk.indexOf('F') + 1;
        var isX = gk.indexOf('X') + 1;
        var isY = gk.indexOf('Y') + 1;
        var isZ = gk.indexOf('Z') + 1;
        var isE = gk.indexOf('E') + 1;
        X = Y = Z = F = S = 0;
        dx = dy = dz = de = 0;
        if (isF) {

            if (G == 1) lf = F1;
            else lf = F0;
            F = Math.min(gd['F'] * 0.0167, 250);
            if (F != lf) lf = F;
            else isF = 0;
            if (G == 1) F1 = lf;
            else F0 = lf;
        }
        if (isX) {
            X = gd['X'] * xyscale;
            if (isRel) X += lx;
            dx = X - lx;
            if (X != lx) lx = X;
            else isX = 0;
			if (Math.abs(X)>31000)warnoverflow=1;
        }
        if (isY) {
            Y = gd['Y'] * xyscale;
            if (isRel) Y += ly;
            dy = Y - ly;
            if (Y != ly) ly = Y;
            else isY = 0;
			if (Math.abs(Y)>31000)warnoverflow=1;
        }
        if (isZ) {
            Z = gd['Z'] * 100;
            if (isRel) Z += lz;
            dz = Z - lz;
            if (Z != lz) lz = Z; // else isZ=0;
        }
        if (isE) {
            E = gd['E'] * eMul;
            if (isRel) E += le;
            le = E;
            //if (E!=le)le=E; else isE=0;
            filament = Math.max(le, filament);
        }

        if (isF) h |= 1 << 3;
        if (isX) h |= 1 << 4;
        if (isY) h |= 1 << 5;
        if (isZ) h |= 1 << 6;
        if (isE) h |= 1 << 7;
        write(h, 1);
        lh = h;

        if (isF) {
            lf = F;
            write(F, 1);
        }
        if (isX) {
            write(X + 30000, 2);
            //log(x);
        }
        if (isY) {
            write(Y + 30000, 2);
        }
        if (isZ) {
            write(Z + 5000, 2);
        }
        if (isE) {
            var de = Math.floor(E - eE);
            //	  if (de<-120) de=-120;
            //	  if (de>120)de=120;
            if (de < -eBound) de = -eBound;
            if (de > eBound) de = eBound;
            //	  de=de;//&0xFFFF;	
            //      ole=E;
            //	  if (de<0)de=0;
            eE = eE + (de);
            write(de + eBound, eSize);
        }
        // save the vertex
        if ((gd['G'] <= 1)) {
            // 3d XYZ to 2D transform
            overtex.push([lx, ly, lz, isE]);
            // add printtime
            printtime += Math.sqrt((dx * dx + dy * dy + dz * dz) * 0.0001) / lf;
        }
        //console.log("G"+gd['G']+" X"+X);
    }
	oxmax=Math.max(oxmax,lx);		
	oxmin=Math.min(oxmin,lx);		
	oymax=Math.max(oymax,ly);		
	oymin=Math.min(oymin,ly);		
	ozmax=Math.max(ozmax,lz);		
	ozmin=Math.min(ozmin,lz);
  if (!cntg28) {
    endcompress();
    cntg28 = 2;
  }
}
var cpos=0;
var decodes="";
function read(n){
	var ac=0;
	for (var i=0;i<n;i++){
		ac+=(compress[cpos+i])<<(i*8);
	}
	cpos+=n;
	return ac;
}
var decoding=0;
var cntg28=0;
var rE=0;
function decodealine(){
	var isM=0;
	var isG=0;
	var isX=0;
	var isY=0;
	var isZ=0;
	var isE=0;
	var isF=0;
	var isS=0;
	var M=0;
	var G=0;
	var X=0;
	var Y=0;
	var Z=0;
	var S=0;
	var F=0;
	var h=read(1);
	var s=0;
	if (h &1){
		isM=1;
		switch ((h >> 1) & 3) {
		  case 0: M = 3; break;
		  case 1: M = 109; break;
		  case 2: decoding=0; return; break;
		}
		if (h & (1 << 3)) {
		  s=read(1);
		  isS = 1;
		  S = s;
		}
		decodes+="M"+M+" S"+S+"\n";
	} else {
		isG=1;
		switch ((h >> 1) & 3) {
		  case 0: G = 0; break;
		  case 1: G = 1; break;
		  case 2:
			G = 28;
			cntg28--;
			break;
		  case 3: 
		        G = 92;
				rE=0;
				
		  break;
		}	
		var x=0;
		decodes+="G"+G;
		if (h & (1 << 3)) {
		  s=read(1);
		  isF = 1;
		  F = s;
		  decodes+=" F"+60*s;
		}
		if (h & (1 << 4)) {
		  x=read(2);
		  isX = 1;
		  X = x / xyMul - 300;
		  decodes+=" X"+mround(X);
		}
		if (h & (1 << 5)) {
		  x=read(2);
		  isY = 1;
		  Y = x / xyMul - 300;
		  decodes+=" Y"+mround(Y);
		}
		if (h & (1 << 6)) {
		  x=read(2);
		  isZ = 1;
		  Z = x / xyMul - 50;
		  decodes+=" Z"+mround(Z);
		}
		if (h & (1 << 7)) {
		  x=read(eSize);
		  isE = 1;
		  rE+=x-eBound;
		  decodes+=" E"+mround((rE)/eMul);
		  //decodes+=" E"+mround4(rE);
		}
		decodes+="\n";

		
	}
	if (cntg28==0) {
		decoding=0;
	}
	
	
}
function decode(){
	cpos=0;
	cntg28=2;
	decoding=1;
	decodes="";
	rE=0;
	
	while (decoding){
		decodealine();
	}
	editor.setValue(decodes,-1);
}

var main_r=0.5;
var main_g=1;
var main_b=0.2;
function randomcolor(){
	main_r=mround(Math.random());
	main_g=mround(Math.random());
	main_b=mround(Math.random());
	var m=Math.max(main_b,Math.max(main_r,main_g));
	main_r/=m;
	main_g/=m;
	main_b/=m;
}
randomcolor();
var letters = '0123456789ABCDEF';
function tohex(v){
	if (v>255)v=255;
	v=Math.floor(v);
    return letters[(v>>4)&15]+letters[v&15];
}
function getColor(v) {
	if (v<0)v=0;
    return "#"+tohex(main_r*v)+tohex(main_g*v)+tohex(main_b*v);
}

function rendergcode(){
	if (overtex.lentgh==0)return;
	xmax=-100000;
	xmin=100000;
	ymax=-100000;
	ymin=100000;
	zmax=-100000;
	zmin=100000;
	

	var vertex=[];
	lines=[];
	var vc=[];
	var lv=0;
	// 3d to 2d transformation + lighting
	for (var i=0;i<overtex.length;i++){
		var ov=overtex[i];
		var tr=transform(ov);
		
		var tx=tr[0];
		var ty=tr[2];
		// save bounding box

		xmax=Math.max(xmax,tx);		
		xmin=Math.min(xmin,tx);		
		ymax=Math.max(ymax,ty);		
		ymin=Math.min(ymin,ty);		
		zmax=Math.max(zmax,tr[1]);		
		zmin=Math.min(zmin,tr[1]);
		// save vertex
		vc=[tx,ty,-tr[1]];
		vertex.push(vc);
		if (ov[3] && lv){
			// cheap fast lighting
			dx=lv[0]-vc[0];
			dz=lv[1]-vc[1];
			dy=lv[2]-vc[2];
			
			l=Math.abs(150*dx/Math.sqrt(dx*dx+dy*dy));
			// if there is extruder value then save the line
			p=vertex.length-1;
			zz=-Math.min(vertex[p][2],vertex[p-1][2]);
			lines.push([p-1,p,l,zz]);
		}
		lv=vc;
	}
	ctx.clearRect(0, 0, 200, 200);
    ///*/ nice background
	var grd=ctx.createLinearGradient(0,0,0,200);
	grd.addColorStop(0,"#88bbFF");
	grd.addColorStop(0.35,"white");
	grd.addColorStop(0.55,"#eeaa33");
	grd.addColorStop(1,"#bb7711");

	ctx.fillStyle="white";
	ctx.fillRect(0,0,200,200);
	//*/
  
	//calculate scale
	var zs=100.0/(zmax-zmin);
	var xs=194.0/(xmax-xmin);
	var ys=194.0/(ymax-ymin);
	
	var sc = Math.min(xs,ys);
	var xa=-xmin*xs;
	var za=-zmin*zs;
	var ya=-ymin*ys;
	var rp=Math.floor(2000/(ozmax-ozmin))+1;
	
	// draw the bed grid
	var gmin=Math.floor(xmin/1000)-15;
	var gmax=Math.floor(xmax/1000)+15;
	
	ctx.strokeStyle="rgba(255,0,0,0.25)";
	for (var i=gmin;i<gmax;i++){
		var v1=transform([i*1000,ymin*14,0]);
		var v2=transform([i*1000,ymax*14,0]);
		var x1=v1[0]*sc+xa+3;
		var x2=v2[0]*sc+xa+3;
		var y1=v1[2]*sc+ya+3;
		var y2=v2[2]*sc+ya+3;
		ctx.beginPath();
		ctx.moveTo(x1, y1);
		ctx.lineTo(x2, y2);
		ctx.stroke();
		
		
	}
	var gmin=Math.floor(zmin/1000)-15;
	var gmax=Math.floor(zmax/1000)+15;
	
	for (var i=gmin;i<gmax;i++){
		var v1=transform([xmin*14,i*1000,0]);
		var v2=transform([xmax*14,i*1000,0]);
		var x1=v1[0]*sc+xa+3;
		var x2=v2[0]*sc+xa+3;
		var y1=v1[2]*sc+ya+3;
		var y2=v2[2]*sc+ya+3;
		ctx.beginPath();
		ctx.moveTo(x1, y1);
		ctx.lineTo(x2, y2);
		ctx.stroke();
		
		
	}
	
	
	// actual rendering
	var front=[];
	for (var i=1;i<lines.length-1;i++){
		var v1=vertex[lines[i][0]];
		var v2=vertex[lines[i][1]];
		// light color
		ll=getColor(lines[i][2]+v1[2]*zs+za);
		// transform to canvas size
		var x1=v1[0]*sc+xa+3;
		var x2=v2[0]*sc+xa+3;
		var y1=v1[1]*sc+ya+3;
		var y2=v2[1]*sc+ya+3;
		for (var j=0;j<rp;j++){
			ctx.beginPath();
			ctx.strokeStyle=ll;
			ctx.moveTo(x1, y1-j);
			ctx.lineTo(x2, y2-j);
			ctx.stroke();
		}
		
	}
    ctx.font = "11px Arial";
    ctx.fillStyle = "white";
    sx = mround((oxmax - oxmin) / 1000);
    sy = mround((oymax - oymin) / 1000);
    sz = mround((ozmax - ozmin) / 1000);
	gram=filament/(333*eMul);
    ctx.fillText("X:" + sx + "  Y:" + sy +"  Z:" + sz + "cm, E: "+mround(filament/(eMul*1000))+"mt",3,11);
	ctx.fillText("W:" + mround(gram) + " gr, Time:"+mround(printtime/55+1)+"m", 3, 23);
    ctx.fillStyle = "black";
    ctx.fillText("X:" + sx + "  Y:" + sy +"  Z:" + sz + "cm, E: "+mround(filament/(eMul*1000))+"mt",2,10);
	ctx.fillText("W:" + mround(gram) + " gr, Time:"+mround(printtime/55+1)+"m", 2, 22);
	
}

var sp=0;
var pv=0;
var cs="";
function showProgress(){
}
function begincompress(paste){
	oxmax=-100000;
	oxmin=100000;
	oymax=-100000;
	oymin=100000;
	ozmax=-100000;
	ozmin=100000;
	eE=ole=lx=ly=lz=le=lf=0;
	
	printtime=0;
	//init2d(0);
	var t0=performance.now();
	
	overtex=[]; // will hold x,y,z
	lines=[]; // will hold n1,n2 that index point to vertex
	compress=[];
	packages=[];
	isRel=0;
	totalgcode=0;
	if (paste)	texts=paste.split("\n"); else texts=getvalue("gcode").split("\n");
	cntg28=2;
	setTimeout(showProgress,200);
 	for (var i=0;i<texts.length;i++){
		addgcode(texts[i]);
		if (i&31==0)pv=i*100.0/texts.length;			
	}
	  h = 1;
	  h |= 2 << 1;
	  write(h, 1);
	var t1=performance.now();
	c1=mround((t1-t0)/1000);
	lines.sort(function (b,a){return a[3]-b[3];})
	rendergcode();
	var t0=performance.now();
	c2=mround((t0-t1)/1000);
	
	$("info").innerHTML=mround(totalgcode/1000000)+" > "+mround(compress.length/1000000)+" Mbyte<br>Ratio "+mround(totalgcode/compress.length)+"<br>Compress "+c1+"seconds"+"<br>Render "+c2+"seconds";
	//progressBar.value=0;
	var s="";
	for (var i=0;i<compress.length;i++){s+=String.fromCharCode(compress[i]);}
	cs=JSON.stringify(s);
}
function urlopen(s){
  var xhr = new XMLHttpRequest();
  xhr.open( "GET","/"+s,true);
  xhr.onload = function(e) {alert(xhr.response);};
  xhr.send();
}
function startprint(){
  urlopen("startjob?jobname=/"+getvalue("jobname")+".gcode");
}
function stopprint(){
  urlopen("stopprint");
}
function pauseprint(){
  urlopen("pauseprint");
}
function resumeprint(){
  urlopen("resumeprint");
}
function heating(){
  urlopen("heating");
}
function cooling(){
  urlopen("cooling");
}
function homing(){
  urlopen("home");
}

var mbody=document.getElementById("body");
var gcode="";
function myFunction(v) {
	if (document.activeElement==$("decode"))return;
	gcode=v.clipboardData.getData('text/plain');
	if (gcode){
		begincompress(gcode);
		//$("gcode").innerHTML=s;
	}
}

mbody.addEventListener("paste", myFunction);
mbody.ondrop = function(e) {
    this.className = '';
    e.preventDefault();

    var file = e.dataTransfer.files[0],
        reader = new FileReader();
		reader.onload = function(event) {
        begincompress(event.target.result);
    };
    console.log(file);
    reader.readAsText(file);

    return false;
}
mbody.ondragover = function() {
    return false;
};
mbody.ondragend = function() {
    return false;
};

var wemosd1=1;
var uploadimage=1;
function upload(){
	var fn=getvalue("jobname")+".gcode";
	function uploadjpg(){
		if (!uploadimage)return;
		c=$("myCanvas");
		c.toBlob(function(blob){
			realupload(blob,fn+".jpg",0);
			},"image/jpeg",0.4);
	}
	realupload(new Blob([new Int8Array(compress).buffer],{type:"text/plain"}),fn,uploadjpg);
}

function realupload(gcode,fname,callback) {
    var xhr = new XMLHttpRequest();
    form = new FormData();
    form.append("file1", gcode, fname);


    xhr.open(
        "POST",
        "http://"+getvalue("wsip")+"/upload",
        true
    );

	//xhr.setRequestHeader('Access-Control-Allow-Headers', '*');
    //xhr.setRequestHeader('Content-type', 'application/ecmascript');
    //xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
	
    var progressBar = $('progress1');
    xhr.onload = function(e) {
        progressBar.value = 0;
        if (!wemosd1) alert(xhr.response);
		//resetflashbutton();
		if (callback)callback();
    };
    // Listen to the upload progress.
    xhr.upload.onprogress = function(e) {
        if (e.lengthComputable) {
            progressBar.value = (e.loaded / e.total) * 100;
            progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
        }
    };
    xhr.send(form);
}

function oldrealupload(gcode,jpg) {
  var xhr = new XMLHttpRequest();
  form = new FormData();
  if (!wemosd1){
	  sx = mround((oxmax - oxmin) / 100);
	  sy = mround((oymax - oymin) / 100);
	  sz = mround((ozmax - ozmin) / 100);
	  gram=filament/(333*eMul);

	  form.append("info",$("uinfo").innerHTML);
	  form.append("fname",$("fname").value);
	  form.append("kat",$("ukategori").value);
	  form.append("sx",sx);
	  form.append("sy",sy);
	  form.append("sz",sz);
	  form.append("se",mround(filament/(1000*eMul)));
	  form.append("tp",mround(printtime));
	  form.append("gram",mround(gram));
	  form.append("file2",jpg,"jpeg.jpg");
	}
  form.append("file1",gcode,"gcode.gcode");
  
  
  xhr.open(
            "POST",
            "/upload",
            true
        );
  var progressBar = $('progress1');
  xhr.onload = function(e) {
	progressBar.value = 0;if(!wemosd1)alert(xhr.response);
  };
  // Listen to the upload progress.
  xhr.upload.onprogress = function(e) {
		if (e.lengthComputable) {
		  progressBar.value = (e.loaded / e.total) * 100;
		  progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
		}
  };

  xhr.send(form);
}
function oldupload(){
	c=$("myCanvas");
	c.toBlob(function(blob){
		realupload(new Blob([new Int8Array(compress).buffer],{type:"text/plain"}),blob);
		},"image/jpeg",0.15);
}

function printhub(){
	var gid=prompt("Please enter object #ID");
	var bt=$("btload");
	if (gid){
		bt.innerHTML=='Loading.';
		var oReq = new XMLHttpRequest();
		oReq.open("GET", "http://karyahub3d.xyz/download?act=Download&gid="+gid, true);
		oReq.responseType = "arraybuffer";

	  oReq.onprogress = function(e) {
			if (bt.innerText=='Loading...')bt.innerText=='Loading.';else bt.innerText=='Loading...';
	  };
		oReq.onload = function (oEvent) {
			bt.innerText=='Load GCODE';
		  var arrayBuffer = oReq.response; // Note: not oReq.responseText
		  if (arrayBuffer) {
			var byteArray = new Uint8Array(arrayBuffer);
			compress=byteArray;
			decode();
			begincompress(decodes);
		  }
		};

		oReq.send(null);	
	}
}


setclick("bt3eeprom", function() {
    document.getElementById("eepromid").innerHTML = "";
    sendgcode("m205");
});
setclick("bt3seteeprom", function() {
    sendgcode("M206 P" + eppos + " S" + getvalue("eepromval"));

});
setevent("change", "eepromid", function() {
    var v = getvalue("eepromid").split(":");
    setvalue("eepromval", v[0]);
    eppos = v[1];
});



var cs="";
compress=[];
//for (var i=0;i<cs.length;i++){compress.push(cs.charCodeAt(i));}
//decode();begincompress(editor.getValue());

</script>

</body>
</html>